/**
 * @(#)LimitSqlExecutorh.java 2010-3-24
 * 
 * Copyright (c) 2000-2010 by ChinanetCenter Corporation.
 *
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * ChinanetCenter Corporation ("Confidential Information").  You
 * shall not disclose such Confidential Information and shall use
 * it only in accordance with the terms of the license agreement
 * you entered into with ChinanetCenter.
 * 
 */

package com.szf.base.dao.ibatis;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.mapping.statement.RowHandlerCallback;
import com.ibatis.sqlmap.engine.scope.StatementScope;
import com.szf.base.dao.Dialect;
import com.szf.util.StringUtil;

public class LimitSqlExecutor extends SqlExecutor {

	private final Logger logger = LoggerFactory.getLogger(LimitSqlExecutor.class);

	private Dialect dialect;

	private boolean enableLimit = true;

	public Dialect getDialect() {
		return dialect;
	}

	public void setDialect(Dialect dialect) {
		if (dialect != null) {
			logger.debug("set ibatis LimitSqlExecutor.dialect = {}", dialect.getClass().getName());
		}
		this.dialect = dialect;
	}

	public boolean isEnableLimit() {
		return enableLimit;
	}

	public void setEnableLimit(boolean enableLimit) {
		this.enableLimit = enableLimit;
	}

	@Override
	public void executeQuery(StatementScope statementScope, Connection conn, String sqlStr,
			Object[] parameters, int skipResults, int maxResults, RowHandlerCallback callback)
			throws SQLException {

		List<Object> result = convert(sqlStr, skipResults, maxResults);
		String sql = String.valueOf(result.get(0));
		int newSkipResults = Integer.valueOf(result.get(1).toString());
		int newMaxResults = Integer.valueOf(result.get(2).toString());

		super.executeQuery(statementScope, conn, sql, parameters, newSkipResults, newMaxResults,
				callback);
	}

	public boolean supportsLimit() {
		if (enableLimit && dialect != null) {
			return dialect.supportsLimit();
		}
		return false;
	}

	/**
	 * 对sql添加行记录条件，根据数据库类型添加分页语句
	 * @param sqlStr
	 * @param skipResults
	 * @param maxResults
	 * @return List(sql,skipResults,maxResults)
	 */
	public List<Object> convert(String sqlStr, int skipResults, int maxResults) {
		List<Object> result = new ArrayList<Object>(3);

		String sql = StringUtil.trim(sqlStr);

		// 添加分页
		if (supportsLimit()
				&& (skipResults != NO_SKIPPED_RESULTS || maxResults != NO_MAXIMUM_RESULTS)) {
			sql = sql.trim();
			if (dialect.supportsLimitOffset()) {
				sql = dialect.getLimitString(sql, skipResults, maxResults);
				skipResults = NO_SKIPPED_RESULTS;
			}
			else {
				sql = dialect.getLimitString(sql, 0, maxResults);
			}
			maxResults = NO_MAXIMUM_RESULTS;
		}

		result.add(sql);
		result.add(skipResults);
		result.add(maxResults);

		return result;
	}
}
